package com.gxh.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.gxh.constant.MessageConstant;
import com.gxh.context.BaseContext;
import com.gxh.dto.UserDTO;
import com.gxh.dto.UserLoginDTO;
import com.gxh.dto.UserPageQueryDTO;
import com.gxh.entity.User;
import com.gxh.exception.LoginFailedException;
import com.gxh.mapper.UserMapper;
import com.gxh.properties.WeChatProperties;
import com.gxh.result.PageResult;
import com.gxh.service.UserService;
import com.gxh.utils.DesensitizationUtil;
import com.gxh.utils.HttpClientUtil;
import com.gxh.vo.UserVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class UserServiceImpl implements UserService {

    @Autowired
    private WeChatProperties weChatProperties;
    @Autowired
    private UserMapper userMapper;


    //微信服务接口地址
    private static final String WX_LOGIN = "https://api.weixin.qq.com/sns/jscode2session";
    //微信服务接口地址
    private static final String WX_PHONE = "https://api.weixin.qq.com/wxa/business/getuserphonenumber";
    //微信服务接口地址
    private static final String WX_ACCESS_TOKEN = "https://api.weixin.qq.com/cgi-bin/token";

    /**
     * 微信登入
     * @param userLoginDTO
     * @return
     */
    public User wxLogin(UserLoginDTO userLoginDTO) {
        //调用微信接口服务,获取微信当前openid和sessionKey
        String openid = getOpenid(userLoginDTO.getLoginCode());
        //获取access_token
        String accessToken = getAccessToken();
        //调取微信手机接口服务，获取当前的手机号
        String phone = getPhone(userLoginDTO.getPhoneCode(), accessToken);
        //判断openid是否为空，如果为空则登录失败
        if (openid == null){
            throw new LoginFailedException(MessageConstant.LOGIN_FAILED);
        }
        //判断当前用户是否为新用户，如果是新用户就自动完成注册
        User  user = userMapper.selectOne(new QueryWrapper<User>().eq("openid", openid));
        if (user == null){
            String nickName = "用户" + (int)(Math.random() * 9000 + 1000); // 生成1000-9999之间的随机数
            user = User.builder()
                    .openid(openid)
                    .nickName(nickName)
                    .createTime(LocalDateTime.now())
                    .phone(phone)
                    .avatarUrl("https://gxh-machine.oss-cn-shanghai.aliyuncs.com/images/b4bd05fb7d1803ec8ae8a83da4e64946.jpg")
                    .build();
            userMapper.insert(user);
        } else if(user.getPhone()!= phone){
            user.setPhone(phone);
            userMapper.updateById(user);
        }


        return user;
    }

    /**
     * 修改用户信息
     * @param userDTO
     */
    public void update(UserDTO userDTO) {
        User user = new User();
        BeanUtils.copyProperties(userDTO, user);
        //判断当前用户是否为空
        Long id = BaseContext.getCurrentId();
        if (id == null){
            throw new LoginFailedException(MessageConstant.LOGIN_FAILED);
        }
        user.setId(id);
        userMapper.updateById(user);
    }

    @Override
    public UserVO getById() {
        Long id = BaseContext.getCurrentId();
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        User user = userMapper.selectOne(queryWrapper.eq("id", id));
        //处理手机号
        String safePhone = "";
        if (user.getPhone() != null) {
            safePhone = DesensitizationUtil.desensitizePhone(user.getPhone());
        }
        return UserVO.builder()
                .id(user.getId())
                .nickName(user.getNickName())
                .phone(safePhone)
                .gender(user.getGender())
                .birthday(user.getBirthday())
                .avatarUrl(user.getAvatarUrl())
                .build();
    }

    /**
     * 用户分页查询
     * @param userPageQueryDTO
     * @return
     */
    public PageResult page(UserPageQueryDTO userPageQueryDTO) {
        PageHelper.startPage(userPageQueryDTO.getPage(), userPageQueryDTO.getPageSize());
        Page<User> page = userMapper.pageQuery(userPageQueryDTO);
        long total = page.getTotal();
        List<User> records = page.getResult();
        log.info("分页查询结果：{}", records);
        return new PageResult(total, records);
    }

    /**
     * 根据id查询用户
     * @param id
     * @return
     */
    public User getByUserId(Long id) {
        User user = userMapper.selectById(id);
        if (user == null){
            return null;
        }
        return user;
    }

    /**
     * 用户注销
     */
    public void deleteById() {
        Long userId = BaseContext.getCurrentId();
        userMapper.deleteById(userId);
    }

    /**
     * 获取微信登录的openid
     * @param code
     * @return
     */
    private String getOpenid(String code) {
        //调用微信接口服务,获取微信当前openid和sessionKey
        Map<String, String> map = new HashMap<>();
        //传入微信接口需要的参数
        map.put("appid", weChatProperties.getAppid());
        map.put("secret", weChatProperties.getSecret());
        map.put("js_code", code);
        map.put("grant_type", "authorization_code");
        //发送请求,获取到返回的json数据
        String json = HttpClientUtil.doGet(WX_LOGIN, map);
        //解析json数据
        JSONObject wxLoginResult = JSONObject.parseObject(json);
        String openid = wxLoginResult.getString("openid");
        return openid;
    }

    /**
     * 获取微信的access_token
     * @return
     */
    private String getAccessToken() {
        //调用微信接口服务,获取微信当前openid和sessionKey
        Map<String, String> map = new HashMap<>();
        //传入微信接口需要的参数
        map.put("appid", weChatProperties.getAppid());
        map.put("secret", weChatProperties.getSecret());
        map.put("grant_type", "client_credential");
        //发送请求,获取到返回的json数据
        String json = HttpClientUtil.doGet(WX_ACCESS_TOKEN, map);
        //解析json数据
        JSONObject accessTokenResult = JSONObject.parseObject(json);
        log.info("access_token：{}", accessTokenResult);
        String accessToken = accessTokenResult.getString("access_token");
        return accessToken;
     }
     /**
     * 获取微信用户手机号
      * @param code,accessToken
      * @return
      */
    private String getPhone(String code, String accessToken) {
        Map<String, String> map = new HashMap<>();
        map.put("code", code);
        try {
            String json = HttpClientUtil.doPost4Json(WX_PHONE+"?access_token="+accessToken, map);
            JSONObject wxPhoneResult = JSONObject.parseObject(json);
            String phone = wxPhoneResult.getJSONObject("phone_info").getString("phoneNumber");
            return phone;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }



}
